#ifndef INTEROPIO_H
#define INTEROPIO_H

#include <memory>
#include <unordered_map>
#include <vector>
#include <list>
// #pragma once

#include "InterOpObject.h"
#include "InterOpProgressTypes.h"
#include "pmi/InterOpShapePMIInfos.h"
namespace AMCAX::Exchange
{
    class InterOpDocumentInstance;
    namespace InterOp
    {
        class InterOpDocumentInstance;
        /// @brief Struct of point 3d.
        ///
        struct Point3D
        {
            double x;
            double y;
            double z;
        };

        /// @brief Facet type for the meta data.
        ///
        enum class FacetType
        {
            FACET_TYPE_TRIANGLE = 0, // Triangular facets.
            FACET_TYPE_QUAD          // Grid facets.
        };

        /// @brief Facet options for th meta data.
        struct FacetOptions
        {
            // Default is triangle.
            FacetType facetType = FacetType::FACET_TYPE_TRIANGLE;
            // Default is 0, means this option will be ignored.
            double maxEdgeLength = 0;
        };

        /// @brief Struct of the output meta data information.
        struct MetaDataInfo
        {
            double volume;
            double area;
            std::list<Point3D> vertexes;
            std::list<std::list<Point3D>> triangles;
            std::string topologyJsonFilePath;
        };

        class IO
        {
        public:
            static IO &GetInstance();

            static void InitLogger();

            void ReadFromFilePath(std::string filePath, std::vector<std::shared_ptr<InterOpObject>> *exchangeObjectList, std::shared_ptr<InterOpDocumentInstance> *rootInterOpDocInstance);
            void WriterToFile(std::string filePath, const std::vector<std::shared_ptr<InterOpObject>> &exchange_shapes, const std::shared_ptr<InterOpDocumentInstance> &docRootInstance);

            bool CheckLicense(const std::string &license);

            
            void SetReporter(InterOp::Reporter::ReporterType reporter) ;
            /// @brief Convert the file from input file path to out file path.
            /// @param inFilePath input file path.
            /// @param outFilePath output file path.
            void Convert(const std::string &inFilePath, const std::string &outFilePath, const std::string &policyFilePath = "");

            void ExportPolicy(const std::string &optionsFilePath) ;

            /// @brief Retrieve the meta data information from the input file.
            /// @param inFilePath input file path.
            /// @param outTopoJsonFilePath output topology json file path.
            /// @param facetOptions meta data facet options.
            /// @return output meta data informations.
            MetaDataInfo GetMetaData(const std::string &inFilePath, const std::string &outTopoJsonFilePath, const FacetOptions &facetOptions) const;

            /// @brief Get document information
            /// @param inFilePath input file path.
            /// @param outJson output document information in json format
            void GetDocumentInfo(const std::string &inFilePath, std::string &outJson);

            /// @brief Get document properties
            /// @param inFilePath input file path.
            /// @param outJson output document properties in json format
            /// @param includingChilding whether return properties of children references
            void GetProperties(const std::string &inFilePath, std::string &outJson, bool includingChildren = false);
            
            
            std::unordered_map<std::string,PMI::InterOpShapePMIInfos> GetPMIInfo(const std::string &inFilePath) ;
        private:
            IO();
            bool checkLicensePass{false};

            std::unordered_map<std::string,PMI::InterOpShapePMIInfos> pmi_ ;
        };
    }
}
#endif